#pragma once
#ifndef __G_WINDOW_H__
#define __G_WINDOW_H__

#include <string>

#include "GVector.h"
#include "GTypes.h"

#include "GMessageHandler.h"


namespace GEngine
{
	enum GWindowType
	{
		G_WT_CAPTIONED	= 0,
		G_WT_POPUP		= 1,
		G_WT_CUSTOM		= 2,
	};

	struct GWindowStyle
	{
		GWindowType		Type;
		union
		{		
			struct GWindowCaptioned
			{
				bool	OnTop;
				bool	Resizable;
				bool	Minimizable;
				bool	Maximizable;
			}	Captioned;
		
			struct GWindowPopup
			{
				bool	OnTop;
				bool	Resizable;
			}	Popup;
		
			struct GWindowCustom
			{
				GUInt32	Properties0;	// Corresponds to Style
				GUInt32	Properties1;	// Corresponds to StyleExt
			}	Custom;
		};
	};

	struct GWindowState
	{
		bool			Enabled;
		bool			Visible;
		bool			Focused;
		bool			Minimized;
		bool			Maximized;
		bool			FullScreen;
		bool			Modal;
	};

	class GWindowMessageHandler : public GMessageHandler
	{
	public:
				GWindowMessageHandler();
				~GWindowMessageHandler();

		GSSize	HandleMessage(const GSystemMessage* Message) OVERRIDE PLATFORM;
	};

	class GWindow
	{
	friend class GCore;
	friend class GWindowMessageHandler;

	protected:
		void*				Handle;
		std::string			Title;

		GInt32				Width;
		GInt32				Height;

		GInt32				PositionX;
		GInt32				PositionY;

		bool				VSynchEnabed;
		GUInt32				VSynchInterval;

		GWindowStyle		Style;
		GWindowState		State;

		GMessageHandler*	MsgHandler;

		virtual void		OnHide();
		virtual void		OnShow();

		virtual void		OnEnable();
		virtual void		OnDisable();

		virtual void		OnFocusGain();
		virtual void		OnFocusLoose();

		virtual void		OnRestore();
		virtual void		OnMinimize();
		virtual void		OnMaximize();

		virtual void		OnWindowed();
		virtual void		OnFullScreen();

		virtual void		OnSizing();
		virtual void		OnSizeEnd();
		virtual void		OnSizeStart();

		virtual void		OnMove(GInt32 NewPositionX, GInt32 NewPositionY);
		virtual void		OnSize(GInt32 NewWidth, GInt32 NewHeight);

		static bool			StaticInitialize() PLATFORM;
		static bool			StaticUninitialize() PLATFORM;

	public:
		static const GWindowState InitialState;
		static const GWindowStyle DefaultStyle;

							GWindow();
							GWindow(GMessageHandler* Handler);
		virtual 			~GWindow();

		void*				GetHandle() const;
		const GWindowState&	GetState() const;

		bool				SetStyle(const GWindowStyle& WindowStyle) PLATFORM;
		const GWindowStyle&	GetStyle() const;

		virtual bool		SetTitle(const char* String) PLATFORM;
		const char*			GetTitle() const;

		virtual bool		SetPosition(GInt32 X, GInt32 Y) PLATFORM;
		void				GetPosition(GInt32& X, GInt32& Y);
		void				GetPosition(GMath::GVector2& Position);
		
		virtual bool		SetSize(GInt32 Width, GInt32 Height) PLATFORM;
		void				GetSize(GInt32& Width, GInt32& Height);
		void				GetSize(GMath::GVector2& Size);

		virtual bool		SetFullScreen(bool Value) PLATFORM;
		bool				GetFullScreen() const;

		virtual bool		SetVSynch(bool Value, GUInt32 Interval = 1) PLATFORM;
		bool				GetVSynch() const;

		void				Enable() PLATFORM;
		void				Disable() PLATFORM;

		virtual void		Show() PLATFORM;
		virtual void		Hide() PLATFORM;
		virtual void		Focus() PLATFORM;

		virtual bool		Restore() PLATFORM;
		virtual bool		Maximize() PLATFORM;
		virtual bool		Minimize() PLATFORM;

		virtual bool		Release() PLATFORM;
		virtual bool		Create(void* Handle) PLATFORM;
		virtual bool		Create(GInt32 X, GInt32 Y, GInt32 W, GInt32 H, const char* Name = NULL, const GWindowStyle& WindowStyle = DefaultStyle, bool ShowImmediately = true) PLATFORM;

	};

}

#endif